//----------------------------------Include-------------------------------------
#include <stdint.h>
#include <math.h>

#include "hpm_math.h"
#include "glbvar.h"
//------------------------------------------------------------------------------

//-----------------------------------Macro--------------------------------------
#define _CFFT_R4
//#define _CFFT_F32
//#define _RFFT_F32
//------------------------------------------------------------------------------

//------------------------------------Type--------------------------------------
typedef struct{
  float  real;
  float  imag;
}t_cmplx;
//------------------------------------------------------------------------------

//---------------------------------Static Var-----------------------------------
#ifdef _CFFT_R4
#endif
#ifdef _CFFT_F32
static arm_cfft_instance_f32         scfft;
#endif
#ifdef _RFFT_F32
static arm_rfft_fast_instance_f32    scfft;
#endif
//------------------------------------------------------------------------------
static uint32_t   N_t[GM_NEED_PT];
//------------------------------------------------------------------------------
static t_cmplx    ucplx[GM_NEED_PT];
static t_cmplx    icplx[GM_NEED_PT];
//------------------------------------------------------------------------------

//--------------------------------Static Func-----------------------------------
static void _FFT(float* pSrc, float* pDesc)
{
#if defined(_CFFT_R4) || defined(_CFFT_F32)
  uint32_t   i,j;
  for(i=0,j=0; i<GM_FFT_NUM; i++){
    pDesc[j] = pSrc[i];  pDesc[j+1] = 0;
    j += 2;
  }
#endif

#ifdef _CFFT_R4
  hpm_dsp_cfft_rd4_f32(pDesc, 10);    //2^10 = 1024
#endif

#ifdef _CFFT_F32
  arm_cfft_f32(&arm_cfft_sR_f32_len1024, pDesc, 0, 1);
#endif

#ifdef _RFFT_F32
  arm_rfft_fast_f32(&scfft, pSrc, pDesc, 0);
#endif
}
//------------------------------------------------------------------------------

//---------------------------------Public Func----------------------------------
//设定参数
void calc_init(void)
{
#ifdef _CFFT_R4
#endif

#ifdef _CFFT_F32
  arm_cfft_init_f32(&scfft, GM_FFT_NUM);
#endif

#ifdef _RFFT_F32
  arm_rfft_fast_init_f32(&scfft, GM_FFT_NUM);
#endif
  
  for(uint32_t i=0; i<GM_NEED_PT; i++){
    N_t[i] = (GM_FFT_NUM*i*GM_BASE_FRQ/GM_SAMP_FRQ);    //0--DC   1--base frq   2--base*2 frq
  }
}

//计算
void calc_para(void)
{
  _FFT(igaf_adc_u, gaf_fft_u);
//_FFT(igaf_adc_i, gaf_fft_i);
  
#if 0
  //all amplitude
  gaf_amp_u[0] = gaf_fft_u[0]/GM_FFT_NUM;
  gaf_amp_i[0] = gaf_fft_i[0]/GM_FFT_NUM;
  for(uint32_t i=1; i<GM_FFT_NUM/2; i++){
    gaf_amp_u[i] = sqrt( gaf_fft_u[2*i]*gaf_fft_u[2*i] + gaf_fft_u[2*i+1]*gaf_fft_u[2*i+1] ) / (GM_FFT_NUM/2);
    gaf_amp_i[i] = sqrt( gaf_fft_i[2*i]*gaf_fft_i[2*i] + gaf_fft_i[2*i+1]*gaf_fft_i[2*i+1] ) / (GM_FFT_NUM/2);
  }
#endif
  
  //complex
  for(uint32_t i=0; i<GM_NEED_PT; i++){
    ucplx[i].real = gaf_fft_u[2*N_t[i]];   ucplx[i].imag = gaf_fft_u[2*N_t[i]+1];
  }
  
  //from complex get amplitude
  gaf_pt_amp_u[0] = ucplx[0].real / GM_FFT_NUM;
  for(uint32_t i=1; i<GM_NEED_PT; i++){
    gaf_pt_amp_u[i] = hpm_dsp_sqrt_f32( ucplx[i].real*ucplx[i].real + ucplx[i].imag*ucplx[i].imag) / (GM_FFT_NUM/2);
  }
}
//-----------------------------------EOF----------------------------------------

/*
just like signal:
(if use signal generator, notice to multiplying by 2)

      ^
1.0V  |         . .
      |       .     .
      |     .         .
      |   .             .
      |  .               .
0.5V  |-------------------------------------.---------
      |                    .               .
      |                     .             .
      |                       .         .
      |                         .     .
      |                           . .
0V    |=================================================>

gaf_pt_amp_x[0] is DC Component, the value = 0.5
gaf_pt_amp_x[1] is base freq   (50Hz)  amplitude, the value = 0.5, not peak-peak; the rms = 0.5*sqrt(2)/2
gaf_pt_amp_x[2] is base freq*2 (100Hz) amplitude
gaf_pt_amp_x[3] is base freq*3 (150Hz) amplitude

if input square or triangular wave, the amplitude of odd(3,5,7...) is very obvious
*/















